package com.zlm.lock;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;

/**
 * @author zlm
 * @date 2025/4/18
 */
public class MyLock {

    AtomicInteger state = new AtomicInteger(0);

    Thread owner = null;

    //头节点
    //Node head = new Node();
    AtomicReference<Node> head = new AtomicReference<>(new Node());
    //尾节点
    //Node tail = new Node();
    AtomicReference<Node> tail = new AtomicReference<>(head.get());
    void lock(){

        if(state.get() == 0){
            if(state.compareAndSet(0,1)){
                System.out.println(Thread.currentThread().getName()+"直接获取到锁");
                owner = Thread.currentThread();
                return;
            }
        }else{
            if(owner == Thread.currentThread()){
                //state.incrementAndGet();
                System.out.println(Thread.currentThread().getName()+"拿到了重入锁，当前充入次数为："+state.incrementAndGet());
                return;
            }
        }
        Node current = new Node();
        current.thread = Thread.currentThread();
        //链表添加尾节点

        while (true){
            Node currentTail = tail.get();
            if (tail.compareAndSet(currentTail,current)){
                current.pre = currentTail;
                currentTail.next = current;
                System.out.println(Thread.currentThread().getName()+"添加到链表尾节点成功");
                break;
            }
        }


        while (true){

            if(current.pre == head.get() && state.compareAndSet(0,1)){
                owner = Thread.currentThread();
                head.set(current);
                current.pre.next = null;
                current.pre = null;
                System.out.println(Thread.currentThread().getName()+"被唤醒拿到锁");
                return;
            }
            LockSupport.park();
        }
    }

    void unlock(){
        if(Thread.currentThread() != this.owner){
            throw new IllegalStateException("当前线程没有持有锁，不能解锁");
        }
        int i = state.get();

        if(i>1){
            state.set(i-1);
            System.out.println(Thread.currentThread().getName()+"当前线程解锁重入锁成功,剩余充入次数"+(i-1));
            return;
        }
        if(i <= 0){
            throw new IllegalStateException("重入锁错误");
        }

        Node headNode = head.get();
        Node next = headNode.next;
        state.set(0);
        if(next != null){
            System.out.println(Thread.currentThread().getName()+"唤醒下一个线程"+next.thread.getName());
            LockSupport.unpark(next.thread);
        }
    }

    static class Node{
        Node pre;
        Node next;
        Thread thread;
    }
}
